<?php

namespace App\Services;

use App\Models\DailyChallenge;
use App\Models\User;
use App\Models\UserNotification;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class DailyChallengeService
{
    /**
     * 获取今日挑战
     */
    public function getTodayChallenge($user)
    {
        $today = now()->toDateString();
        
        // 检查用户今天是否已经有挑战
        $existingChallenge = DB::table('user_daily_challenges')
            ->join('daily_challenges', 'user_daily_challenges.challenge_id', '=', 'daily_challenges.id')
            ->where('user_daily_challenges.user_id', $user->id)
            ->where('user_daily_challenges.challenge_date', $today)
            ->select('daily_challenges.*', 'user_daily_challenges.is_completed', 'user_daily_challenges.completed_at', 'user_daily_challenges.reward_earned')
            ->first();

        if ($existingChallenge) {
            return $this->formatChallengeData($existingChallenge);
        }

        // 为用户分配新的挑战
        $challenge = $this->assignTodayChallenge($user);
        
        if (!$challenge) {
            return null;
        }

        return $this->formatChallengeData($challenge);
    }

    /**
     * 完成挑战
     */
    public function completeChallenge($user, $challenge, array $completionData = [])
    {
        $today = now()->toDateString();

        // 检查用户今天是否有这个挑战
        $userChallenge = DB::table('user_daily_challenges')
            ->where('user_id', $user->id)
            ->where('challenge_id', $challenge->id)
            ->where('challenge_date', $today)
            ->first();

        if (!$userChallenge) {
            return [
                'success' => false,
                'message' => '今日没有此挑战任务'
            ];
        }

        if ($userChallenge->is_completed) {
            return [
                'success' => false,
                'message' => '今日挑战已经完成过了'
            ];
        }

        // 验证完成条件
        if (!$this->validateCompletion($challenge, $completionData)) {
            return [
                'success' => false,
                'message' => '挑战完成条件不满足'
            ];
        }

        try {
            // 更新挑战状态
            DB::table('user_daily_challenges')
                ->where('user_id', $user->id)
                ->where('challenge_id', $challenge->id)
                ->where('challenge_date', $today)
                ->update([
                    'is_completed' => true,
                    'completed_at' => now(),
                    'reward_earned' => $challenge->reward_points
                ]);

            // 发放奖励
            if ($user->statistics) {
                $user->statistics->addExperiencePoints($challenge->reward_points);
            }

            // 计算连续完成天数
            $consecutiveDays = $this->calculateConsecutiveDays($user);

            // 发送完成通知
            $this->sendCompletionNotification($user, $challenge);

            // 检查连续完成成就
            $this->checkConsecutiveAchievements($user, $consecutiveDays);

            Log::info('Daily challenge completed', [
                'user_id' => $user->id,
                'challenge_id' => $challenge->id,
                'reward_points' => $challenge->reward_points
            ]);

            return [
                'success' => true,
                'challenge' => $this->formatChallengeData($challenge, true),
                'reward_earned' => $challenge->reward_points,
                'is_first_completion' => $consecutiveDays === 1,
                'consecutive_days' => $consecutiveDays,
            ];

        } catch (\Exception $e) {
            Log::error('Failed to complete daily challenge', [
                'user_id' => $user->id,
                'challenge_id' => $challenge->id,
                'error' => $e->getMessage()
            ]);

            throw $e;
        }
    }

    /**
     * 获取挑战历史
     */
    public function getChallengeHistory($user, $page = 1, $perPage = 20)
    {
        $offset = ($page - 1) * $perPage;

        $challenges = DB::table('user_daily_challenges')
            ->join('daily_challenges', 'user_daily_challenges.challenge_id', '=', 'daily_challenges.id')
            ->where('user_daily_challenges.user_id', $user->id)
            ->orderBy('user_daily_challenges.challenge_date', 'desc')
            ->select(
                'daily_challenges.*',
                'user_daily_challenges.challenge_date',
                'user_daily_challenges.is_completed',
                'user_daily_challenges.completed_at',
                'user_daily_challenges.reward_earned'
            )
            ->offset($offset)
            ->limit($perPage)
            ->get();

        $total = DB::table('user_daily_challenges')
            ->where('user_id', $user->id)
            ->count();

        $formattedChallenges = $challenges->map(function ($challenge) {
            return $this->formatChallengeData($challenge);
        });

        // 统计数据
        $stats = $this->getChallengeStats($user);

        return [
            'challenges' => $formattedChallenges,
            'pagination' => [
                'current_page' => $page,
                'per_page' => $perPage,
                'total' => $total,
                'last_page' => ceil($total / $perPage),
            ],
            'stats' => $stats,
        ];
    }

    /**
     * 为用户分配今日挑战
     */
    private function assignTodayChallenge($user)
    {
        $today = now()->toDateString();
        
        // 获取用户能力水平，推荐合适难度的挑战
        $userAbility = $user->latestAbilities();
        $recommendedDifficulty = $this->getRecommendedDifficulty($userAbility);

        // 获取用户最近完成的挑战，避免重复
        $recentChallengeIds = DB::table('user_daily_challenges')
            ->where('user_id', $user->id)
            ->where('challenge_date', '>=', now()->subDays(7)->toDateString())
            ->pluck('challenge_id')
            ->toArray();

        // 选择合适的挑战
        $challenge = DailyChallenge::active()
            ->where('difficulty_level', '<=', $recommendedDifficulty)
            ->whereNotIn('id', $recentChallengeIds)
            ->inRandomOrder()
            ->first();

        // 如果没找到合适的，就随机选一个
        if (!$challenge) {
            $challenge = DailyChallenge::active()
                ->whereNotIn('id', $recentChallengeIds)
                ->inRandomOrder()
                ->first();
        }

        // 如果还是没有，就选择任意一个
        if (!$challenge) {
            $challenge = DailyChallenge::active()
                ->inRandomOrder()
                ->first();
        }

        if ($challenge) {
            // 为用户分配这个挑战
            DB::table('user_daily_challenges')->insert([
                'user_id' => $user->id,
                'challenge_id' => $challenge->id,
                'challenge_date' => $today,
                'is_completed' => false,
                'reward_earned' => 0,
            ]);
        }

        return $challenge;
    }

    /**
     * 获取推荐难度
     */
    private function getRecommendedDifficulty($userAbility)
    {
        if (!$userAbility) {
            return 2; // 默认初级难度
        }

        $averageScore = $userAbility->getTotalScore();

        if ($averageScore >= 80) {
            return 5; // 专家
        } elseif ($averageScore >= 65) {
            return 4; // 困难
        } elseif ($averageScore >= 50) {
            return 3; // 中等
        } elseif ($averageScore >= 35) {
            return 2; // 容易
        } else {
            return 1; // 简单
        }
    }

    /**
     * 验证完成条件
     */
    private function validateCompletion($challenge, array $completionData)
    {
        // 这里可以根据不同的挑战类型实现具体的验证逻辑
        // 暂时简化处理，认为所有挑战都可以完成
        return true;
    }

    /**
     * 计算连续完成天数
     */
    private function calculateConsecutiveDays($user)
    {
        $consecutiveDays = 1;
        $currentDate = now()->toDateString();
        
        // 从昨天开始往前查找连续完成的天数
        for ($i = 1; $i <= 30; $i++) { // 最多查找30天
            $checkDate = now()->subDays($i)->toDateString();
            
            $completed = DB::table('user_daily_challenges')
                ->where('user_id', $user->id)
                ->where('challenge_date', $checkDate)
                ->where('is_completed', true)
                ->exists();
            
            if ($completed) {
                $consecutiveDays++;
            } else {
                break;
            }
        }

        return $consecutiveDays;
    }

    /**
     * 发送完成通知
     */
    private function sendCompletionNotification($user, $challenge)
    {
        UserNotification::create([
            'user_id' => $user->id,
            'notification_type' => 'daily_challenge',
            'title' => '🎯 挑战完成！',
            'content' => "恭喜完成今日挑战「{$challenge->title}」！获得 {$challenge->reward_points} 经验值。",
            'scheduled_at' => now()
        ]);
    }

    /**
     * 检查连续完成成就
     */
    private function checkConsecutiveAchievements($user, $consecutiveDays)
    {
        // 这里可以触发连续完成相关的成就
        // 比如连续3天、7天、30天等
        if (in_array($consecutiveDays, [3, 7, 14, 30])) {
            UserNotification::create([
                'user_id' => $user->id,
                'notification_type' => 'achievement',
                'title' => '🔥 连续挑战达成！',
                'content' => "太棒了！你已经连续完成 {$consecutiveDays} 天的每日挑战！",
                'scheduled_at' => now()
            ]);
        }
    }

    /**
     * 获取挑战统计
     */
    private function getChallengeStats($user)
    {
        $totalChallenges = DB::table('user_daily_challenges')
            ->where('user_id', $user->id)
            ->count();

        $completedChallenges = DB::table('user_daily_challenges')
            ->where('user_id', $user->id)
            ->where('is_completed', true)
            ->count();

        $totalRewards = DB::table('user_daily_challenges')
            ->where('user_id', $user->id)
            ->where('is_completed', true)
            ->sum('reward_earned');

        $consecutiveDays = $this->getCurrentConsecutiveDays($user);

        return [
            'total_challenges' => $totalChallenges,
            'completed_challenges' => $completedChallenges,
            'completion_rate' => $totalChallenges > 0 ? round(($completedChallenges / $totalChallenges) * 100, 1) : 0,
            'total_rewards' => $totalRewards,
            'current_consecutive_days' => $consecutiveDays,
        ];
    }

    /**
     * 获取当前连续天数
     */
    private function getCurrentConsecutiveDays($user)
    {
        $consecutiveDays = 0;
        
        // 从今天开始往前查找连续完成的天数
        for ($i = 0; $i < 30; $i++) {
            $checkDate = now()->subDays($i)->toDateString();
            
            $completed = DB::table('user_daily_challenges')
                ->where('user_id', $user->id)
                ->where('challenge_date', $checkDate)
                ->where('is_completed', true)
                ->exists();
            
            if ($completed) {
                $consecutiveDays++;
            } else {
                break;
            }
        }

        return $consecutiveDays;
    }

    /**
     * 格式化挑战数据
     */
    private function formatChallengeData($challenge, $isCompleted = null)
    {
        return [
            'id' => $challenge->id,
            'challenge_key' => $challenge->challenge_key,
            'title' => $challenge->title,
            'description' => $challenge->description,
            'difficulty_level' => $challenge->difficulty_level,
            'difficulty_text' => $this->getDifficultyText($challenge->difficulty_level),
            'reward_points' => $challenge->reward_points,
            'is_completed' => $isCompleted ?? (bool)$challenge->is_completed,
            'completed_at' => $challenge->completed_at ?? null,
            'reward_earned' => $challenge->reward_earned ?? 0,
            'challenge_date' => $challenge->challenge_date ?? now()->toDateString(),
        ];
    }

    /**
     * 获取难度文本
     */
    private function getDifficultyText($level)
    {
        $levels = [
            1 => '简单',
            2 => '容易',
            3 => '中等',
            4 => '困难',
            5 => '专家'
        ];

        return $levels[$level] ?? '未知';
    }
}